import sys
import csv
import pandas as pd
from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import pyqtSlot

from view.Ui_mainWindow import Ui_MainWindow

from staff import Staff


# 读取文件中存储的用户名与密码
def readAdminInfo(filename="data/admin.txt"):
    with open(filename, 'r+', encoding='utf-8') as f:
        s = [i[:-1].split(',') for i in f.readlines()]  # 读取文件里的每行文本
        return s  # 返回所有读取到的用户名和密码


class MainWindow(QMainWindow, Ui_MainWindow):  # 多重继承QMainWindow和Ui_MainWindow
    def __init__(self):
        super(MainWindow, self).__init__()  # 先调用父类QMainWindow的初始化方法
        self.setupUi(self)
        self.initUI()  # 再调用setupUi方法

    def initUI(self):
        # 利用tableWidget展示数据
        # 员工信息相关的数据展示在staffList上
        self.staffList.setColumnCount(7)  # 表格设置为7列
        headers = ['工号', '姓名', '性别', '第一季度', '第二季度', '第三季度', '第四季度']  # 表格标题栏
        self.staffList.setHorizontalHeaderLabels(headers)  # 表格设置标题栏
        # 下面两行用于设置列宽自适应
        self.staffList.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.staffList.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents)
        # 隐藏默认行号
        self.staffList.verticalHeader().setHidden(True)
        # tableWidget 进行排序
        self.staffList.setSortingEnabled(True)
        # 从staff_data.csv中读取数据,并展示在table上
        staff_list = pd.read_csv(r'data/staff_data.csv', header=None, encoding='utf-8')
        for staff in staff_list.itertuples():
            self.add_line_staffList(staff)

        # 员工排名相关的数据展示在rankList上
        self.rankList.setColumnCount(3)  # 表格设置为4列
        headers = ['工号', '姓名', '总业绩']
        self.rankList.setHorizontalHeaderLabels(headers)  # 表格设置标题栏
        # 下面两行用于设置列宽自适应
        self.rankList.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.rankList.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents)
        # 隐藏默认行号
        # self.rankList.verticalHeader().setHidden(True)
        # tableWidget 进行排序
        self.rankList.setSortingEnabled(True)
        # 填充数据到rankList
        self.fill_rankList()

        # 从admin.txt中读取数据
        info_list = readAdminInfo()
        self.nameInput.setText(info_list[0][0])
        self.pwdInput.setText(info_list[0][1])

    # staffList 表格添加行信息的方法封装
    def add_line_staffList(self, staff):
        rowCount = self.staffList.rowCount()  # 取表格当前行数
        self.staffList.setRowCount(rowCount + 1)  # 表格增加一行
        for i in range(7):  # 循环处理staff_data的7个数据
            item = QTableWidgetItem(str(staff[i + 1]))

            item.setTextAlignment(QtCore.Qt.AlignCenter)  # 设置单元格内容居中
            self.staffList.setItem(rowCount, i, item)  # 指定单元格和行和列,以及数据

    # 填充rankList表格的数据
    def fill_rankList(self):
        count = self.staffList.rowCount()
        for i in range(count):
            self.rankList.setRowCount(i + 1)

            # 编号
            item1 = QTableWidgetItem(self.staffList.item(i, 0).text())
            item1.setTextAlignment(QtCore.Qt.AlignCenter)  # 设置单元格内容居中
            self.rankList.setItem(i, 0, item1)  # 指定单元格和行和列,以及数据

            # 姓名
            item2 = QTableWidgetItem(self.staffList.item(i, 1).text())
            item2.setTextAlignment(QtCore.Qt.AlignCenter)  # 设置单元格内容居中
            self.rankList.setItem(i, 1, item2)  # 指定单元格和行和列,以及数据

            total = 0  # 总业绩
            for j in range(3, 7, 1):  # 3，4，5，6 位分别是季度一、二、三、四
                total = total + float(self.staffList.item(i, j).text())
            item3 = QTableWidgetItem(str(total))  # 单元格对象
            item3.setTextAlignment(QtCore.Qt.AlignCenter)  # 设置单元格内容居中
            self.rankList.setItem(i, 2, item3)  # 指定单元格和行和列,以及数据

            self.rankList.sortByColumn(2, QtCore.Qt.DescendingOrder)  # 以总成绩排序

    # 搜索功能的实现
    @pyqtSlot()
    def on_searchBtn_clicked(self):
        try:
            text = self.searchInput.text()  # 获取搜索文本
            items = self.staffList.findItems(text, QtCore.Qt.MatchExactly)  # 搜索模式为完全匹配
            row = items[0].row()  # 获取搜索到的行号
            self.staffList.selectRow(row)  # 选中对应行
        except:
            QMessageBox.information(self, '提示信息', '未查询到相关数据!')

    # 添加功能
    @pyqtSlot()
    def on_addBtn_clicked(self):
        count = self.staffList.rowCount()  # 获取总行数
        self.staffList.setRowCount(count + 1)  # 添加1行

        for i in range(7):
            item = QTableWidgetItem()  # 创建单元格
            item.setTextAlignment(QtCore.Qt.AlignCenter)  # 居中
            self.staffList.setItem(count, i, item)  # 设置单元格的值

    # 删除功能
    @pyqtSlot()
    def on_delBtn_clicked(self):
        try:
            items = self.staffList.selectedItems()  # 获取选中行
            item = items[0]  # 默认单选
            self.staffList.removeRow(item.row())  # 删除指定行
        except:
            QMessageBox.information(self, '提示信息', '请选中要操作的数据的编号!')

    # 部门查询功能
    @pyqtSlot()
    def on_departBtn_clicked(self):
        try:
            text = self.department.currentText()  # 获取选择框的值
            count = self.staffList.columnCount()  # 全部行数
            if text == "全部":
                for i in range(count):  # 显示全部内容
                    self.staffList.showRow(i)
            else:
                items = self.staffList.findItems(text, QtCore.Qt.MatchStartsWith)  # 搜索模式为开头匹配
                # 隐藏所有的行
                for i in range(count):
                    self.staffList.hideRow(i)
                # 将满足查找条件的行显示
                for item in items:  # 匹配到的单元格对象
                    self.staffList.showRow(item.row())  # 只显示查找到的行
        except:
            QMessageBox.information(self, '提示信息', '请选中要操作的数据的编号!')

    # 业绩分析(季度)
    @pyqtSlot()
    def on_analysisBtn_clicked(self):
        text = self.quarterCombox.currentText()
        s = "最高业绩:%s \n最低业绩:%s\n平均业绩:%s" % (self.getMax(int(text)), self.getMin(int(text)), self.getMean(int(text)))
        QMessageBox.information(self, "第" + text + "季度", s)

    # 更新排行榜
    @pyqtSlot()
    def on_updateRankBtn_clicked(self):
        self.fill_rankList()

    # 重写关闭时的事件,保存数据
    def closeEvent(self, event):
        reply = QMessageBox.question(self, '提示信息', '确认要关闭窗口？',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
            self.saveTableDataToCSV()  # 保存表格数据到本地文件
            self.saveAdminInfo()  # 保存管理员数据
        else:
            event.ignore()

    # 最高业绩
    def getMax(self, quarter):
        count = self.staffList.rowCount()  # 全部行数
        maxP = 0
        for i in range(count):
            val = float(self.staffList.item(i, quarter+2).text())
            maxP = val if (maxP < val) else maxP
        return maxP

    # 最低业绩
    def getMin(self, quarter):
        count = self.staffList.rowCount()  # 全部行数
        minP = 99999
        for i in range(count):
            val = float(self.staffList.item(i, quarter+2).text())
            minP = val if (minP > val) else minP
        return minP

    # 平均业绩
    def getMean(self, quarter):
        count = self.staffList.rowCount()  # 全部行数
        sumP = 0.0
        for i in range(count):
            sumP = sumP + float(self.staffList.item(i, quarter + 2).text())
        return "%.2f" % (sumP / count)

    # 将tableWidget数据保存到csv
    def saveTableDataToCSV(self, filename="data/staff_data.csv"):
        row = self.staffList.rowCount()
        column = self.staffList.columnCount()
        with open(filename, "w", encoding="utf-8", newline="") as f:
            writer = csv.writer(f)  # 初始化写入对象
            for i in range(row):
                row_list = []
                for j in range(column):
                    row_list.append(self.staffList.item(i, j).text())
                writer.writerow(row_list)

    # 将管理员数据保存到txt
    def saveAdminInfo(self, filename="data/admin.txt"):
        with open(filename, "w", encoding="utf-8") as f:
            f.write("%s,%s\n" % (self.nameInput.text(), self.pwdInput.text()))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    # app.setStyle(QStyleFactory.create("Fusion"))
    ui = MainWindow()
    ui.show()
    sys.exit(app.exec_())
